import {getAccessToken, getJsapiTicket} from './../../api/login'
import {getUserInfo} from '@/api/login'
import * as dd from 'dingtalk-jsapi'
import crypto from '../crypto'
import {getStorage, removeStorage, setStorage} from '../localstoreage'
import {getSession, setSession} from '../sessionStorage'
import {ant_design_vue} from '../global/antDesignVue'

type GetArgType<T> = T extends (arg: infer P) => Promise<any> ? P : T
type GetPromiseDataType<T> = T extends (arg: any) => Promise<infer P> ? P : T

type ComplexPickerArg = GetArgType<typeof dd.biz.contact.complexPicker>
type ChooserArg = {
  multiple?: boolean //是否多选
  max?: number //最大可选人数
  users?: string[]
}
type DepartmentsPickerArg = GetArgType<typeof dd.biz.contact.departmentsPicker>
type SaveFileArg = GetArgType<typeof dd.biz.cspace.saveFile>
type UploadAttachmentArg = GetArgType<typeof dd.biz.util.uploadAttachment>
type PreviewArg = GetArgType<typeof dd.biz.cspace.preview>

const {message} = ant_design_vue

const corpId = 'dinge40921088d438cae35c2f4657eb6378f'

const agentId = 1996175114

// const agentId = 2469699578

// 获取钉钉corpId的方法
export function getUrlParams(key: string) {
  let query = window.location.search.substring(1)
  let vars = query.split('&')
  for (let i = 0; i < vars.length; i++) {
    let pair = vars[i].split('=')
    if (pair[0] == key) return pair[1]
  }
  return false
}

export function requestAuthCode() {
  return new Promise((resolve: (data: User.Info) => void, reject: (data: false) => void) => {
    console.log('dd.env:', dd.env.platform)
    if (dd.env.platform !== 'notInDingTalk') {
      // 获取免登授权码
      dd.runtime.permission
        .requestAuthCode({
          corpId: corpId
        })
        .then(res => {
          // 获取用户信息
          getUserInfo({code: res.code})
            .then(userInfores => {
              console.log('成功获取用户信息，存储用户Id')

              setSession('userDDId', userInfores.data.userId)

              resolve(userInfores.data)
            })
            .catch(err => {
              message.error({
                content: '获取用户信息时发生错误！' + JSON.stringify(err)
              })
              reject(false)
            })
        })
        .catch(err => {
          console.error(err)
          message.error({
            content: '登录失败0xrequestAuthCode ' + JSON.stringify(err, null, 2)
          })
          reject(false)
        })
    } else {
      if (process.env.NODE_ENV === 'development') {
        let developer = getSession('developer')
        if (developer == 1) {
          console.log('开发环境，根据当前登陆者（developer），使用王趁义的userInfo')
          resolve({
            avatar:
              'https://static-legacy.dingtalk.com/media/lQLPM5RcHulGuTjNAyDNAyCw41sH3GX_tOUDgeif0MAdAA_800_800.png',
            deptId: '598431022',
            deptloaderId: 'manager8211',
            deptName: '信息化软件部',
            roleLevel: 1,
            scoreWeight: undefined,
            userId: 'manager8211',
            userName: '王趁义'
          })
        } else if (developer == 2) {
          console.log('开发环境，根据当前登陆者（developer），使用魏东的userInfo')

          resolve({
            avatar:
              'https://static-legacy.dingtalk.com/media/lQLPDhrkRRYXwrjMlsyWsEzwmYOhlOr0AaM9esgAZgA_150_150.png',
            deptId: '1',
            deptloaderId: 'manager8211',
            deptName: '信息化软件部',
            scoreWeight: undefined,
            roleLevel: 1,
            userId: '38424845683478',
            userName: '包伟方'
          })
        } else {
          console.log('开发环境，根据当前登陆者（developer），使用张行的userInfo')
          // resolve({
          //   avatar:
          //     'https://static-legacy.dingtalk.com/media/lQLPM5RcHulGuTjNAyDNAyCw41sH3GX_tOUDgeif0MAdAA_800_800.png',
          //   deptId: '598431022',
          //   deptloaderId: 'manager8211',
          //   deptName: '信息化软件部',
          //   roleLevel: 1,
          //   scoreWeight: undefined,
          //   userId: 'manager8211',
          //   userName: '王趁义'
          // })

          // resolve({
          //   avatar:
          //     'https://static-legacy.dingtalk.com/media/lQLPDhrkRRYXwrjMlsyWsEzwmYOhlOr0AaM9esgAZgA_150_150.png',
          //   deptId: '598431022',
          //   deptloaderId: 'manager8211',
          //   deptName: '信息化软件部',
          //   scoreWeight: undefined,
          //   roleLevel: 1,
          //   userId: '1618391431999590',
          //   userName: '魏东'
          // })

          // resolve({
          //   "userId": "15942870820258629",
          //   "deptName": "信息化软件部",
          //   "userName": "张行",
          //   "avatar": "https://static-legacy.dingtalk.com/media/lQLPDhvML2o7oQXNAyDNAyCwsa7JS7pcUpQDHzXS5QAcAA_800_800.png",
          //   "deptId": '598431022',
          //   "roleLevel": 3,
          //   "deptloaderId": "manager8211",
          //   "scoreWeight": 0
          // })

          // resolve({
          //   "userId": "15942870820258629",
          //   "deptName": "信息化软件部",
          //   "userName": "张行",
          //   "avatar": "https://static-legacy.dingtalk.com/media/lQLPDhvML2o7oQXNAyDNAyCwsa7JS7pcUpQDHzXS5QAcAA_800_800.png",
          //   "deptId": '598431022',
          //   "roleLevel": 3,
          //   "deptloaderId": "manager8211",
          //   "scoreWeight": 0
          // })

          // resolve({
          //   "userId": "16558881343308293",
          //   "deptName": "行政管理部",
          //   "userName": "戚淑婷",
          //   "avatar": "https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg",
          //   "deptId": '357716159',
          //   "roleLevel": 3,
          //   "deptloaderId": "15645335230197906",
          //   "scoreWeight": 0
          // })

          // resolve({
          //   userId: '0414175760941995643',
          //   deptName: '火凤凰队',
          //   userName: '吴碧喜',
          //   avatar:
          //     'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '102460202',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16457055830112453',
          //   deptName: '薪酬绩效组',
          //   userName: '钱亚铃',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 2,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16098948831859823',
          //   deptName: '应用设备研发部',
          //   userName: '段欣念',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD4PvLqonHj_NAznNAzk_825_825.jpg',
          //   deptId: '438939100',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '2326245129885618',
          //   deptName: '项目部',
          //   userName: '沈建',
          //   avatar: 'http://d.lohand.com:8808/static/img/avatar.png',
          //   deptId: '103859044',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '09163404651296193',
          //   deptName: '结构工艺部',
          //   userName: '黄超',
          //   avatar: 'http://d.lohand.com:8808/static/img/avatar.png',
          //   deptId: '111541350',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16873072771893261',
          //   deptName: '信息化软件部',
          //   userName: '王伟伦',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          //  resolve({
          //   userId: '16364187601207604',
          //   deptName: 'xxxxx',
          //   userName: '雷卫常',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16883488789052836',
          //   deptName: 'xxxxx',
          //   userName: '蒋新奇',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '112413671620201990',
          //   deptName: 'xxxxx',
          //   userName: '余先贵',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })
          // resolve({
          //   userId: '17113377949778958',
          //   deptName: 'xxxxx',
          //   userName: '汤红',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '15925520867252472',
          //   deptName: 'xxxxx',
          //   userName: '张梦蓝',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '357332991',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          resolve({
            userId: '16873072771893261',
            deptName: '信息化软件部',
            userName: '王伟伦',
            avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
            deptId: '598431022',
            roleLevel: 3,
            deptloaderId: '',
            scoreWeight: 0
          })

          // resolve({
          //   userId: '17530617549404588',
          //   deptName: '技术支持组',
          //   userName: '魏逸鸣',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '15756817188562633',
          //   deptName: '品质部',
          //   userName: '王晓锋',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16284690745469944',
          //   deptName: '售后',
          //   userName: '钱赟峰',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // 官俊豪
          // resolve({
          //   userId: '245045012123202680',
          //   deptName: 'xxxxx',
          //   userName: '官俊豪',
          //   avatar: 'http://d.lohand.com:8808/static/img/avatar.png',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // 周霞
          // resolve({
          //   userId: '0547573332708534',
          //   deptName: 'xxxxx',
          //   userName: '周霞',
          //   avatar: 'http://d.lohand.com:8808/static/img/avatar.png',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '15687703489981609',
          //   deptName: 'xxxxx',
          //   userName: '陈艳芬',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '026022616026143473',
          //   deptName: 'xxxxx',
          //   userName: '曹振宇',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16455997995638624',
          //   deptName: 'xxxxx',
          //   userName: '夏宣云',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '17124514065657952',
          //   deptName: 'xxxxx',
          //   userName: '刘文豪',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16808343329211539',
          //   deptName: 'xxxxx',
          //   userName: '杨石宝',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '1715648221175439',
          //   deptName: 'xxxxx',
          //   userName: '黄慧',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '0547573332708534',
          //   deptName: 'xxxxx',
          //   userName: '周霞',
          //   avatar: 'legacy.dingtalk.com/media/lADPDgQ9r4_ZrZjNAbDNAbA_432_432.jpg',
          //   deptId: '598431022',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '225607504226310734',
          //   deptName: '薪酬绩效组',
          //   userName: '李浩泉',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '38424845683478',
          //   deptName: '薪酬绩效组',
          //   userName: '包伟方',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 2,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16302954017977312',
          //   deptName: '薪酬绩效组',
          //   userName: '于法振',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16213073893408304',
          //   deptName: '薪酬绩效组',
          //   userName: '李福元',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16395536690226394',
          //   deptName: '薪酬绩效组',
          //   userName: '许峰',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '15915774746793183',
          //   deptName: '薪酬绩效组',
          //   userName: '杨红伟',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16455997995638624',
          //   deptName: '薪酬绩效组',
          //   userName: '夏宣云',
          //   avatar:
          //     'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '750498046',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '16074819763578360',
          //   deptName: '天津办事处',
          //   userName: '薛伟',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPD3W5UrquEyHNBDjNBDg_1080_1080.jpg',
          //   deptId: '579911157',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '096412115221374169',
          //   deptName: '软硬件一部',
          //   userName: '吴从芳',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPDgQ9qk-GiyHNAbDNAbA_432_432.jpg',
          //   deptId: '579911157',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })

          // resolve({
          //   userId: '026022616026143473',
          //   deptName: '品质部',
          //   userName: '曹振宇',
          //   avatar: 'https://static-legacy.dingtalk.com/media/lADPDgQ9qk-GiyHNAbDNAbA_432_432.jpg',
          //   deptId: '579911157',
          //   roleLevel: 3,
          //   deptloaderId: '',
          //   scoreWeight: 0
          // })
        }
      } else {
        message.error({
          content: '非钉钉容器无法使用！'
        })
        reject(false)
      }
    }
  })
}

/**
 *
 * @returns accessToken和jsapiTicket
 */
function getAccessTokenAndJsapiTicker() {
  return new Promise(
    async (resolve: (data: {accessToken: string; jsapiTicket: string}) => void, reject) => {
      let accessToken = getStorage('accessToken')
      if (!accessToken) {
        // 获取accesstoken
        let tokenRes = await getAccessToken()
        if (tokenRes) {
          setStorage('accessToken', tokenRes.data)
          accessToken = tokenRes.data
        } else {
          removeStorage('jsapiTicket')
          message.error({
            content: 'accessToekn获取失败！'
          })
          return reject(false)
        }
      }

      let jsapiTicket = getStorage('jsapiTicket')

      if (!jsapiTicket) {
        let jsapiTicketRes = await getJsapiTicket()
        if (jsapiTicketRes) {
          let data = JSON.parse(jsapiTicketRes.data)
          if (data.errmsg === 'ok') {
            setStorage('jsapiTicket', data.ticket, 2)
            return resolve({accessToken: accessToken, jsapiTicket: data.ticket})
          } else {
            console.log('jsapiTicketRes.data 返回状态非ok', data)
            return reject(false)
          }
        } else {
          removeStorage('jsapiTicket')
          message.error({
            content: 'JsapiTicket获取失败！'
          })
          return reject(false)
        }
      } else {
        return resolve({accessToken: accessToken, jsapiTicket: jsapiTicket})
      }
    }
  )
}

/**
 * 钉钉jsapi鉴权
 * 文档说明每个页面只需要调用一次
 * 单页面引用spa的router切换视为同一个页面， 只需要调用一次
 *
 *
 *
 * .catch可不处理，在调用reject返回错误时，已做错误提示
 *
 * @returns Promise<boolean>
 */
export function ddConfig<O = any, S = any>(fn: (arg: O) => Promise<S>, option: O) {
  return new Promise(
    (
      resolve: (
        data: (ReturnType<typeof fn> extends Promise<infer P> ? P : any) | 'cancel'
      ) => void,
      reject: (data: false) => void
    ) => {
      console.log('ddObject', dd)

      if (dd.env.platform === 'notInDingTalk') {
        message.error({
          content: '非钉钉容器无法使用！'
        })
        return reject(false)
      }

      let ddjsapiConfig = getSession('ddjsapiConfig')

      if (ddjsapiConfig === 'success') {
        fn(option)
          .then(res => {
            // 设置鉴权标识 ddjsapiConfig为success
            // 后续在调用dd.ready时，先获取并判断ddjspiConfig是否为success
            setSession('ddjsapiConfig', 'success')
            resolve(res)
          })
          .catch(err => {
            if (err.errorMessage.indexOf('Cancel') !== -1) {
              console.log('ddReady fn cancel', err)
              resolve('cancel')
            } else {
              console.log('ddReady fn 执行报错 1', err)
              reject(false)
            }
          })
      } else {
        try {
          getAccessTokenAndJsapiTicker()
            .then(res => {
              // 必填 时间戳 获取当前时间戳
              const timeStamp = new Date().getTime() + ''

              // 必填，签名  hash路由: url 为window.location.origin ;history路由: url 为window.location.href
              const signature = crypto.sha256Encrypt(
                encodeURI(
                  'jsapi_ticket=' +
                    res.jsapiTicket +
                    '&noncestr=dingding_h5&timestamp=' +
                    timeStamp +
                    '&url=' +
                    window.location.origin +
                    '/'
                )
              )

              dd.config({
                agentId, // 必填，微应用ID
                corpId, //必填，企业ID
                timeStamp: timeStamp, // 必填，生成签名的时间戳
                nonceStr: 'dingding_h5', // 必填，自定义固定字符串。
                signature: signature, // 必填
                type: 0, //选填。0表示微应用的jsapi,1表示服务窗的jsapi；不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持
                jsApiList: [
                  'runtime.info',
                  'runtime.permission.requestAuthCode',
                  'biz.contact.choose',
                  'biz.ding.post',
                  'biz.util.openLink',
                  'biz.contact.complexPicker',
                  'device.message.confirm',
                  'device.message.alert',
                  'device.message.prompt',
                  'biz.ding.create',
                  'biz.ding.post',
                  'biz.contact.departmentsPicker',
                  'biz.cspace.saveFile',
                  'biz.util.uploadAttachment',
                  'biz.cspace.preview'
                ] // 必填，需要使用的jsapi列表，注意：不要带dd。
              })

              ddReady<O, S>(fn, option)
                .then(res => {
                  // 设置鉴权标识 ddjsapiConfig为success
                  // 后续在调用dd.ready时，先获取并判断ddjspiConfig是否为success
                  setSession('ddjsapiConfig', 'success')
                  resolve(res)
                })
                .catch(err => {
                  if (err.errorMessage.indexOf('Cancel') !== -1) {
                    console.log('ddReady fn cancel', err)
                    setSession('ddjsapiConfig', 'success')
                    resolve('cancel')
                  } else {
                    console.log('ddReady fn 执行报错 2', err)
                    setSession('ddjsapiConfig', 'error')
                    reject(false)
                  }
                })

              dd.error(error => {
                console.log(error)
                if (error.errorMessage.toLocaleLowerCase() !== 'cancel') {
                  message.error({
                    content: '鉴权错误，请排查' + JSON.stringify(error, null, 2)
                  })
                  setSession('ddjsapiConfig', 'error')
                  reject(false)
                }
              })
            })
            .catch(err => {
              setSession('ddjsapiConfig', 'error')
              // 不用做错误处理
              reject(false)
            })
        } catch (e) {
          message.warning({
            content: '鉴权故障，请排查' + JSON.stringify(e, null, 2)
          })
          setSession('ddjsapiConfig', 'error')
          reject(false)
        }
      }
    }
  )
}

/**
 * 每次调用钉钉jsapi时，请在前调用此方法
 *
 * 此方法会返回一个promise，在.then中执行钉钉jsapi
 *
 * .catch不需要处理，挂载即可
 *
 * @returns Promise
 */
export function ddReady<O = any, S = any>(fn: (arg: O) => Promise<S>, option: O) {
  console.log(fn, option)
  return new Promise(
    (
      resolve: (data: ReturnType<typeof fn> extends Promise<infer P> ? P : any) => void,
      reject: (data: false) => void
    ) => {
      try {
        dd.ready(() => {
          console.log(fn, option)
          fn(option)
            .then(res => {
              resolve(res)
            })
            .catch(err => {
              reject(err)
            })
        })
      } catch (err) {
        message.warning({
          content: 'ddReady故障:\n' + JSON.stringify(err, null, 2)
        })
        reject(false)
      }
    }
  )
}

/**
 * 通讯录选人
 * 选择部门与人
 *
 * @returns Promise
 */
export function getDepartAndUser(option?: ComplexPickerArg) {
  type ComplexPickerPromistDataType = GetPromiseDataType<typeof dd.biz.contact.complexPicker>
  const defaultOption: ComplexPickerArg = Object.assign(
    {
      title: '选择部门或人', //标题
      corpId, //企业的corpId
      multiple: true, //是否多选
      limitTips: '选人超出界限', //超过限定人数返回提示
      maxUsers: 1000, //最大可选人数
      pickedUsers: [], //已选用户
      pickedDepartments: [], //已选部门
      disabledUsers: [], //不可选用户
      disabledDepartments: [], //不可选部门
      requiredUsers: [], //必选用户（不可取消选中状态）
      requiredDepartments: [], //必选部门（不可取消选中状态）
      appId: agentId, //微应用Id，企业内部应用查看AgentId
      permissionType: 'GLOBAL', //可添加权限校验，选人权限，目前只有GLOBAL这个参数
      responseUserOnly: false, //返回人，或者返回人和部门
      startWithDepartmentId: 0, //仅支持0和-1 Android端选择部门和人时的开始位置。 0：表示从企业根目录开始;-1：表示从自己所在部门开始
      deptId: -1 //仅支持0和-1 IOS端选择部门和人时的开始位置。 -1：表示从企业根目录开始;0：表示从自己所在部门开始
    },
    option
  )
  defaultOption.limitTips = `最多可选${defaultOption.maxUsers}人`
  return new Promise(
    (
      resolve: (data: ComplexPickerPromistDataType | 'cancel') => void,
      reject: (data: false) => void
    ) => {
      ddConfig<ComplexPickerArg, ComplexPickerPromistDataType>(
        dd.biz.contact.complexPicker,
        defaultOption
      )
        .then(res => {
          console.log('getDepartAndPerson 已选择', res)
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          message.warning({
            content: '选择部门与人失败'
          })
          reject(false)
        })
    }
  )
}

/**
 * 通讯录选人
 * 选择人员
 *
 * @returns Promise
 */
export function getDDUsers(option?: ChooserArg) {
  console.log('option', option)

  type ChooseDataType = GetPromiseDataType<typeof dd.biz.contact.choose>
  const defaultOption: ChooserArg = Object.assign(
    {
      corpId, //企业的corpId
      multiple: true, //是否多选
      max: 1000, //最大可选人数
      users: [] //必选部门（不可取消选中状态）
    },
    option
  )
  return new Promise(
    (resolve: (data: ChooseDataType | 'cancel') => void, reject: (data: false) => void) => {
      console.log('钉钉选择通讯录提交数据', dd.biz.contact.choose, defaultOption)

      ddConfig<ChooserArg, ChooseDataType>(dd.biz.contact.choose, defaultOption)
        .then(res => {
          console.log('getUsers 已选择', res)
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          message.warning({
            content: '选择员工失败'
          })
          reject(false)
        })
    }
  )
}

/**
 * 通讯录选人
 * 选择部门
 *
 * @returns Promise
 */
export function getDeparts(option?: DepartmentsPickerArg) {
  type DepartmentsPickerDataType = GetPromiseDataType<typeof dd.biz.contact.departmentsPicker>
  const defaultOption: DepartmentsPickerArg = Object.assign(
    {
      title: '选择部门', //标题
      appId: agentId, //微应用Id，企业内部应用查看AgentId
      corpId, //企业的corpId
      multiple: true, //是否多选
      limitTips: '选人超出界限', //超过限定人数返回提示
      maxUsers: 1000, //最大可选人数
      pickedDepartments: [], //已选部门
      disabledDepartments: [], //不可选部门
      requiredDepartments: [], //必选部门（不可取消选中状态）
      permissionType: 'GLOBAL' //可添加权限校验，选人权限，目前只有GLOBAL这个参数
    },
    option
  )
  return new Promise(
    (
      resolve: (data: DepartmentsPickerDataType | 'cancel') => void,
      reject: (data: false) => void
    ) => {
      ddConfig<DepartmentsPickerArg, DepartmentsPickerDataType>(
        dd.biz.contact.departmentsPicker,
        defaultOption
      )
        .then(res => {
          console.log('getDepart 已选择', res)
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          message.warning({
            content: '选择部门失败'
          })
          reject(false)
        })
    }
  )
}

/**
 * 保存文件到钉盘
 *
 * @returns Promise
 */
export function ddSaveFile(option?: SaveFileArg) {
  type PormiseDataType = GetPromiseDataType<typeof dd.biz.cspace.saveFile>
  const defaultOption: SaveFileArg = Object.assign(
    {
      corpId, //企业的corpId
      name: '测试附件',
      url: '#iAEHAqRmaWxlA6h5dW5kaXNrMATOITPgiwXNBlAGzT2hB85jrAzRCM0B4A'
    },
    option
  )
  return new Promise(
    (resolve: (data: PormiseDataType | 'cancel') => void, reject: (data: false) => void) => {
      ddConfig<SaveFileArg, PormiseDataType>(dd.biz.cspace.saveFile, defaultOption)
        .then(res => {
          console.log('ddSaveFile 已上传', res)
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          message.warning('保存文件到钉盘失败!')
          reject(false)
        })
    }
  )
}

/**
 * 上传文件到钉盘
 *
 * @returns Promise
 */
export function ddUploadAttachment(option?: UploadAttachmentArg) {
  type PormiseDataType = GetPromiseDataType<typeof dd.biz.util.uploadAttachment>
  const defaultOption: UploadAttachmentArg = Object.assign(
    {
      types: ['photo', 'file', 'space'] //PC端支持["photo","file","space"]
    },
    option
  )
  return new Promise(
    (resolve: (data: PormiseDataType | 'cancel') => void, reject: (data: false) => void) => {
      ddConfig<UploadAttachmentArg, PormiseDataType>(dd.biz.util.uploadAttachment, defaultOption)
        .then(res => {
          console.log('ddSaveFile 已上传', res)
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          message.warning('保存文件到钉盘失败!')
          reject(false)
        })
    }
  )
}

/**
 * 预览钉盘文件
 *
 * @returns Promise
 */
export function ddPreview(option: Omit<PreviewArg, 'corpId'>) {
  type PormiseDataType = GetPromiseDataType<typeof dd.biz.cspace.preview>
  const defaultOption: PreviewArg = Object.assign(
    {
      corpId //企业的corpId
    },
    option
  )
  return new Promise(
    (resolve: (data: PormiseDataType | 'cancel') => void, reject: (data: false) => void) => {
      ddConfig<PreviewArg, PormiseDataType>(dd.biz.cspace.preview, defaultOption)
        .then(res => {
          console.log('预览打开', res)
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          message.warning('预览打开失败!')
          reject(false)
        })
    }
  )
}
